﻿#ifndef C3FDTTECPLOTDATFILEREADER_H
#define C3FDTTECPLOTDATFILEREADER_H
#include "mainWidgetsAPI.h"
#include <QString>
#include <QHash>
#include <QVector>
#include <QList>
#include <QTextStream>

namespace MainWidget
{
	enum class PackingMethod : int {
		POINT,
		BLOCK
	};

	enum class ValLocation : int {
		NODAL,
		CELLCENTERED
	};

	class MAINWIDGETSAPI C3fdTecDatZone
	{
	public:
		PackingMethod getPackingMethod() { return m_PackingMethod; }
		void setPackingMethod(PackingMethod method) { m_PackingMethod = method; }
		QString getTitle() { return m_Title; }
		void setTitle(QString title) { m_Title = title; }
		int getNumOfCell() {
			int num = 1;
			num *= m_Dims[0] > 1 ? m_Dims[0] - 1 : 1;
			num *= m_Dims[1] > 1 ? m_Dims[1] - 1 : 1;
			num *= m_Dims[2] > 1 ? m_Dims[2] - 1 : 1;
			return num;
		}
		int getNumOfPoint() { return m_Dims[0] * m_Dims[1] * m_Dims[2]; }
		QVector<int> getDims() { return m_Dims; }
		int getDimI() { return m_Dims[0]; }
		int getDimJ() { return m_Dims[1]; }
		int getDimK() { return m_Dims[2]; }
		void setDimI(int i) { m_Dims[0] = i; }
		void setDimJ(int j) { m_Dims[1] = j; }
		void setDimK(int k) { m_Dims[2] = k; }
		QHash<int, ValLocation>  getValLocations() { return m_VarLocation; }
		void setValLocations(QHash<int, ValLocation>  data) { m_VarLocation = data; }
		QList<QVector<double>> getDatas() { return m_Data; }
		void addData(QVector<double> data) { m_Data.push_back(data); }
		void setDatas(QList<QVector<double>> data) { m_Data = data; }
		bool is3DPoint() { return m_Is3DPoint; }
		void set3DPoint(bool is3DPoint) { m_Is3DPoint = is3DPoint; }

	private:
		PackingMethod m_PackingMethod = PackingMethod::POINT;
		QString m_Title = "";
		QVector<int> m_Dims = { 1, 1, 1 };
		QHash<int, ValLocation> m_VarLocation = {};
		QList<QVector<double>> m_Data = {};
		bool m_Is3DPoint = false;
	};
	class MAINWIDGETSAPI C3fdTecDatObject
	{
	public:
		QString getTitle() { return m_Title; }
		void setTitle(QString title) { m_Title = title; }
		QList<QString> getVariables() { return m_Variables; }
		void addVariables(QString variable) { m_Variables.push_back(variable); }
		void setVariables(QList<QString> variables) { m_Variables = variables; }
		QList<C3fdTecDatZone *> getZones() { return m_Zones; }
		void addZone(C3fdTecDatZone *zone) { m_Zones.push_back(zone); }
		void setZones(QList<C3fdTecDatZone *> zones) { m_Zones = zones; }

	private:
		QString m_Title = "";
		QList<QString> m_Variables = {};
		QList<C3fdTecDatZone *> m_Zones = {};
	};

	class MAINWIDGETSAPI C3fdTecplotAsciiFileReader
	{
	public:
		C3fdTecplotAsciiFileReader() = default;
		~C3fdTecplotAsciiFileReader() = default;
		C3fdTecDatObject *parse(QString fileName);

	private:
		QHash<QString, QString> readZoneProperty(QString line);
		QHash<int, ValLocation> parseVarLocation(QString varlocation);
		QList<QVector<double>> readPointPackingZoneData(QTextStream &dat, int ix, int jy, int kz, int eachRowItemNum = 1);
		QList<QVector<double>> readBlockPackingZoneData(QTextStream &dat, int ix, int jy, int kz, int numOfVar, QHash<int, ValLocation> locs);
	};
}
#endif